﻿using AutoMapper;
using YDT_UserService.Applictions.DTOs;
using YDT_UserService.Applictions.Interfaces;
using YDT_UserService.Domain.Entities;
using YDT_UserService.Domain.Enums;
using YDT_UserService.Domain.Interfaces;

namespace YDT_UserService.Applictions.Services
{
    /// <summary>
    /// 用户应用服务实现 - 协调领域对象完成业务用例
    /// </summary>
    public class UserService : IUserService
    {
        private readonly IUserRepository _userRepository;
        private readonly IMapper _mapper;

        /// <summary>
        /// 构造函数 - 依赖注入
        /// </summary>
        public UserService(IUserRepository userRepository, IMapper mapper)
        {
            _userRepository = userRepository;
            _mapper = mapper;
        }

        /// <summary>
        /// 根据ID获取用户
        /// </summary>
        public async Task<UserDto?> GetUserByIdAsync(Guid id)
        {
            var user = await _userRepository.GetByIdAsync(id);
            return _mapper.Map<UserDto>(user);
        }

        /// <summary>
        /// 根据用户名获取用户
        /// </summary>
        public async Task<UserDto?> GetUserByUserNameAsync(string userName)
        {
            var user = await _userRepository.GetByUserNameAsync(userName);
            return _mapper.Map<UserDto>(user);
        }

        /// <summary>
        /// 获取所有用户
        /// </summary>
        public async Task<IEnumerable<UserDto>> GetAllUsersAsync()
        {
            var users = await _userRepository.GetAllAsync();
            return _mapper.Map<IEnumerable<UserDto>>(users);
        }

        /// <summary>
        /// 根据状态获取用户
        /// </summary>
        public async Task<IEnumerable<UserDto>> GetUsersByStatusAsync(UserStatus status)
        {
            var users = await _userRepository.GetByStatusAsync(status);
            return _mapper.Map<IEnumerable<UserDto>>(users);
        }

        /// <summary>
        /// 分页查询用户
        /// </summary>
        public async Task<(IEnumerable<UserDto> Users, int TotalCount)> GetPagedUsersAsync(UserQueryDto query)
        {
            var (users, totalCount) = await _userRepository.GetPagedAsync(query.PageIndex, query.PageSize);
            var userDtos = _mapper.Map<IEnumerable<UserDto>>(users);
            return (userDtos, totalCount);
        }

        /// <summary>
        /// 创建用户
        /// </summary>
        public async Task<UserDto> CreateUserAsync(CreateUserDto createUserDto)
        {
            // 检查用户名是否已存在
            if (await _userRepository.UserNameExistsAsync(createUserDto.UserName))
            {
                throw new ArgumentException($"用户名 '{createUserDto.UserName}' 已存在");
            }

            // 检查手机号是否已存在
            if (await _userRepository.PhoneExistsAsync(createUserDto.UserPhone))
            {
                throw new ArgumentException($"手机号 '{createUserDto.UserPhone}' 已被使用");
            }

            // 创建用户实体
            var user = new User(
                createUserDto.UserName,
                createUserDto.Password,
                createUserDto.UserNickname,
                createUserDto.UserPhone,
                createUserDto.UserQQ
            );

            // 保存到数据库
            await _userRepository.AddAsync(user);

            return _mapper.Map<UserDto>(user);
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        public async Task<UserDto?> UpdateUserAsync(Guid id, UpdateUserDto updateUserDto)
        {
            var user = await _userRepository.GetByIdAsync(id);
            if (user == null) return null;

            // 更新用户基本信息
            user.UpdateBasicInfo(
                updateUserDto.UserNickname,
                updateUserDto.UserPhone,
                updateUserDto.UserQQ
            );

            // 保存到数据库
            await _userRepository.UpdateAsync(user);

            return _mapper.Map<UserDto>(user);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        public async Task<bool> DeleteUserAsync(Guid id)
        {
            var user = await _userRepository.GetByIdAsync(id);
            if (user == null) return false;

            await _userRepository.DeleteAsync(id);
            return true;
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        public async Task<bool> ChangePasswordAsync(Guid id, ChangePasswordDto changePasswordDto)
        {
            var user = await _userRepository.GetByIdAsync(id);
            if (user == null) return false;

            // 验证当前密码
            if (!user.VerifyPassword(changePasswordDto.CurrentPassword))
            {
                throw new ArgumentException("当前密码不正确");
            }

            // 设置新密码
            user.SetPassword(changePasswordDto.NewPassword);

            // 保存到数据库
            await _userRepository.UpdateAsync(user);
            return true;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        public async Task<UserDto?> LoginAsync(LoginDto loginDto)
        {
            var user = await _userRepository.GetByUserNameAsync(loginDto.UserName);
            if (user == null) return null;

            // 验证密码
            if (!user.VerifyPassword(loginDto.Password))
            {
                return null;
            }

            // 检查用户状态
            if (user.Status != UserStatus.Active)
            {
                throw new InvalidOperationException("用户已被禁用，无法登录");
            }

            // 记录登录时间
            user.RecordLogin();
            await _userRepository.UpdateAsync(user);

            return _mapper.Map<UserDto>(user);
        }

        /// <summary>
        /// 激活用户
        /// </summary>
        public async Task<UserDto?> ActivateUserAsync(Guid id)
        {
            var user = await _userRepository.GetByIdAsync(id);
            if (user == null) return null;

            user.Activate();
            await _userRepository.UpdateAsync(user);

            return _mapper.Map<UserDto>(user);
        }

        /// <summary>
        /// 禁用用户
        /// </summary>
        public async Task<UserDto?> DeactivateUserAsync(Guid id)
        {
            var user = await _userRepository.GetByIdAsync(id);
            if (user == null) return null;

            user.Deactivate();
            await _userRepository.UpdateAsync(user);

            return _mapper.Map<UserDto>(user);
        }
    }
}
